<script setup lang="tsx">
import Iconify from '@iconify/iconify'
import { ElIcon } from 'element-plus'
import { useDesign } from 'fetm-hooks'
import { IsUtils } from 'fetm-utils'
/**
 * 1.支持 iconify 标准图标(注意：无网环境慎用，需要本地化部署iconify-api服务)
 * 2.支持svg snippets 代码段
 * 3.支持本地svg以'svg-icon:'起始引用，需借助插件vite-plugin-svg-icons
 */
import { computed, ref, unref, useAttrs, watchEffect } from 'vue'

defineOptions({
  name: 'Icon',
})
const props = withDefaults(
  defineProps<{
    icon: string
    color?: string
    size?: number | string
    hoverColor?: string
    useErrorContent?: boolean
    errorContent?: string
    onClick?: (...args: any[]) => any
  }>(),
  {
    errorContent: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v4a1 1 0 0 0 1 1h3m0-5v10m3-9v8a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V8a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1zm7-1v4a1 1 0 0 0 1 1h3m0-5v10"/></svg>`,
  },
)
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('icon')

const attrs = useAttrs()

const elRef = ref<HTMLElement | undefined>()

const isLocal = computed(() => props.icon.startsWith('svg-icon:'))

const symbolId = computed(() => {
  return unref(isLocal)
    ? `#icon-${props.icon.split('svg-icon:')[1]}`
    : props.icon
})

const getIconifyStyle = computed(() => {
  const { color, size } = props
  return {
    fontSize:
      size != undefined
        ? IsUtils.isNumber(size)
          ? `${size}px`
          : `${size}`
        : 'inherit',
    color: color ? `${color}` : 'inherit',
  }
})

async function updateIcon(icon: string) {
  const el = unref(elRef)
  if (unref(isLocal) || !el || !icon)
    return
  if (icon.startsWith('<svg') && icon.endsWith('</svg>')) {
    el.innerHTML = icon
  }
  else {
    try {
      await Iconify.loadIcon(icon)
      const svg = Iconify.renderSVG(icon, {})
      if (svg) {
        el.textContent = ''
        el.appendChild(svg)
      }
    }
    catch {
      if (props.useErrorContent) {
        el.innerHTML = props.errorContent
      }
    }
  }
}

watchEffect(() => {
  if (!unref(isLocal))
    updateIcon(unref(symbolId))
})
</script>

<template>
  <ElIcon :class="prefixCls" :size="size" :color="color" v-bind="attrs" @click="onClick">
    <span ref="elRef" :class="`${prefixCls}-span`" :style="getIconifyStyle">
      <svg v-if="isLocal" aria-hidden="true">
        <use :xlink:href="symbolId" />
      </svg>
    </span>
  </ElIcon>
</template>

<style lang="less" scoped>
@prefix-cls: ~'fetm-icon';

.@{prefix-cls}:hover {
  :deep(svg) {
    color: v-bind('hoverColor');
  }
}
</style>
